package w9

// 总结几种 socket 粘包的解包方式: fix length/delimiter based/length field based frame decoder。尝试举例其应用
// https://www.cnblogs.com/kex1n/p/6502002.html
// 实现一个从 socket connection 中解码出 goim 协议的解码器。

// TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包，从接收缓冲区看，后一包数据的头紧接着前一包数据的尾。
// 出现粘包现象的原因是多方面的，它既可能由发送方造成，也可能由接收方造成

// 粘包出现原因
//
//简单得说，在流传输中出现，UDP不会出现粘包，因为它有消息边界(参考Windows网络编程)
//
//1发送端需要等缓冲区满才发送出去，造成粘包
//
//2接收方不及时接收缓冲区的包，造成多个包接收
//
//具体点：
//
//（1）发送方引起的粘包是由TCP协议本身造成的，TCP为提高传输效率，发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少，通常TCP会根据优化算法把这些数据合成一包后一次发送出去，这样接收方就收到了粘包数据。
//
//（2）接收方引起的粘包是由于接收方用户进程不及时接收数据，从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区，用户进程从该缓冲区取数据，若下一包数据到达时前一包数据尚未被用户进程取走，则下一包数据放到系统接收缓冲区时就接到前一包数据之后，而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据，这样就一次取到了多包数据。
//
//粘包情况有两种，一种是粘在一起的包都是完整的数据包，另一种情况是粘在一起的包有不完整的包。
//
//不是所有的粘包现象都需要处理，若传输的数据为不带结构的连续流数据（如文件传输），则不必把粘连的包分开（简称分包）。但在实际工程应用中，传输的数据一般为带结构的数据，这时就需要做分包处理。
//
//在处理定长结构数据的粘包问题时，分包算法比较简单；在处理不定长结构数据的粘包问题时，分包算法就比较复杂。特别是粘在一起的包有不完整的包的粘包情况，由于一包数据内容被分在了两个连续的接收包中，处理起来难度较大。实际工程应用中应尽量避免出现粘包现象。
//
//
//
//为了避免粘包现象，可采取以下几种措施：
//
//（1）对于发送方引起的粘包现象，用户可通过编程设置来避免，TCP提供了强制数据立即传送的操作指令push，TCP软件收到该操作指令后，就立即将本段数据发送出去，而不必等待发送缓冲区满；
//
//（2）对于接收方引起的粘包，则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施，使其及时接收数据，从而尽量避免出现粘包现象；
//
//（3）由接收方控制，将一包数据按结构字段，人为控制分多次接收，然后合并，通过这种手段来避免粘包。
//
//
//
//以上提到的三种措施，都有其不足之处。
//
//（1）第一种编程设置方法虽然可以避免发送方引起的粘包，但它关闭了优化算法，降低了网络发送效率，影响应用程序的性能，一般不建议使用。
//
//（2）第二种方法只能减少出现粘包的可能性，但并不能完全避免粘包，当发送频率较高时，或由于网络突发可能使某个时间段数据包到达接收方较快，接收方还是有可能来不及接收，从而导致粘包。
//
//（3）第三种方法虽然避免了粘包，但应用程序的效率较低，对实时应用的场合不适合。
//
//
//
//一种比较周全的对策是：接收方创建一预处理线程，对接收到的数据包进行预处理，将粘连的包分开。对这种方法我们进行了实验，证明是高效可行的。
//
//具体可以参考：http://blog.csdn.net/soli/article/details/1297109
//
//
//
//TCP无保护消息边界的解决
//
//针对这个问题，一般有3种解决方案：
//
//(1)发送固定长度的消息
//
//(2)把消息的尺寸与消息一块发送
//
//(3)使用特殊标记来区分消息间隔

// fix length

// delimiter based

// length field based frame decoder
